#include "Administrador.h"

Administrador::Administrador(const string& nombreProceso, bool logActivo) :
		Proceso(nombreProceso, logActivo), semaforoUtilizandoCaja(
				Constantes::ARCHIVO_SEMAFORO_CAJA, 1, 0), semaforoPeticionCaja(
				Constantes::ARCHIVO_PETICION_CAJA_ADMINISTRADOR, 500, 1), prioridadCaja(
				1), colaMensajesCaja(Constantes::ARCHIVO_COLA_MENSAJES_CAJA,'a') {

}

Administrador::~Administrador() {

}

void Administrador :: eliminar() {
	semaforoPeticionCaja.eliminar();
}

void Administrador::contarDineroCaja() {
	// Tiempo que tarda en consultar
	sleep(
			GeneradorRandom::obtenerNumero(
					Constantes::MINIMO_TIEMPO_CONSULTA_ADMINISTRADOR,
					Constantes::MAXIMO_TIEMPO_CONSULTA_ADMINISTRADOR));
	unsigned long int dineroCaja = caja.contarDinero();
	stringstream ss;
	ss << dineroCaja;
	string msg = string("Conte el dinero de la caja, hay: $") + ss.str();
	getLogger().info(msg);
	semaforoUtilizandoCaja.v(); // Aviso que termine de usar la caja
}

Semaforo& Administrador :: getSemaforoPeticionCaja() {
	return semaforoPeticionCaja;
}

int Administrador :: getPrioridadCaja() const {
	return prioridadCaja;
}

void Administrador::run() {
	int codigoSalida = 0; // Para ver si termino run por error o por la signal

	// event handler para la senial SIGINT (-2)
	SIGINT_Handler sigint_handler;
	// se registra el event handler declarado antes
	SignalHandler::getInstance()->registrarHandler(SIGINT, &sigint_handler);
	MensajePeticionCaja mpc;
	mpc.idDemandanteDeCaja = 0;
	mpc.mtype = prioridadCaja;

	//TODO loggear
	while (sigint_handler.getGracefulQuit() == 0) {
		// El administrador espera para consultar un cierto tiempo
		sleep(
				GeneradorRandom::obtenerNumero(
						Constantes::MINIMO_ADMINISTRADOR_CONSULTA_CADA,
						Constantes::MAXIMO_ADMINISTRADOR_CONSULTA_CADA));
		// Mando mensaje a la cola de mensajes para decir que estoy esperando
		colaMensajesCaja.escribir(mpc); // TODO Ver errores
		// Espero hasta que el asignador me desbloquee
		semaforoPeticionCaja.p();
		// Aca ya tengo el acceso a la caja para mi, cuento
		contarDineroCaja();
	}

	if (codigoSalida == 0) {
		getLogger().warn("Se recibio la senial SIGINT, el proceso se termina.");
	}
	SignalHandler::destruir();
}
